//人脸识别工具库（WSC版本）
import * as faceapi from 'face-api.js';

// 定义人脸描述符接口（存储人脸数据的结构）
interface FaceDescriptor {
  name: string;
  descriptor: Float32Array; //128维特征向量
}

// 模型路径（指向 public/weights）
const MODEL_URL = '/weights';

// 从 localStorage 加载已存储的人脸数据
const loadStoredFaces = (): FaceDescriptor[] => {
  const storedData = localStorage.getItem('wsc_faceDescriptors');
  if (!storedData) return [];

  try {
    // 将存储的数据转换回 Float32Array（类型化数组）
    return JSON.parse(storedData, (key, value) => {
      if (key === 'descriptor') {
        return new Float32Array(Object.values(value));
      }
      return value;
    });
  } catch (error) {
    console.error('加载存储的人脸数据失败:', error);
    return [];
  }
};

// 存储已录入的人脸特征
let faceDescriptors: FaceDescriptor[] = loadStoredFaces();

// 保存人脸数据到 localStorage
const saveFaceDescriptors = () => {
  try {
    localStorage.setItem(
      'wsc_faceDescriptors',
      JSON.stringify(faceDescriptors)
    );
    console.warn('人脸数据已保存到本地存储');
  } catch (error) {
    console.error('保存人脸数据失败:', error);
  }
};

// 初始化模型
export async function initFaceAPI() {
  // 为 face-api.js 设置 willReadFrequently
  const tempCanvas = document.createElement('canvas');
  tempCanvas.getContext('2d', { willReadFrequently: true });

  await faceapi.nets.tinyFaceDetector.loadFromUri(MODEL_URL);
  await faceapi.loadFaceLandmarkModel(MODEL_URL);
  await faceapi.loadFaceRecognitionModel(MODEL_URL);
  console.warn('WSC人脸识别模型加载完成');
}

// 从图片中提取人脸特征
export async function getFaceDescriptor(
  image: HTMLImageElement | HTMLVideoElement
) {
  const detection = await faceapi
    .detectSingleFace(image, new faceapi.TinyFaceDetectorOptions())
    .withFaceLandmarks()
    .withFaceDescriptor();
  return detection?.descriptor;
}

// 录入人脸（存储特征）
export function registerFace(name: string, descriptor: Float32Array) {
  faceDescriptors.push({ name, descriptor });
  saveFaceDescriptors(); // 保存到本地存储
  console.warn(`已录入: ${name}`);
}

// 获取所有已录入的人脸
export function getAllFaces(): FaceDescriptor[] {
  return faceDescriptors;
}

// 删除指定名字的人脸
export function deleteFace(name: string): boolean {
  const initialLength = faceDescriptors.length;
  faceDescriptors = faceDescriptors.filter(face => face.name !== name);

  if (faceDescriptors.length < initialLength) {
    saveFaceDescriptors(); // 保存更改到本地存储
    console.warn(`已删除: ${name}`);
    return true;
  }
  return false;
}

// 清空所有人脸数据
export function clearAllFaces() {
  faceDescriptors = [];
  localStorage.removeItem('wsc_faceDescriptors');
  console.warn('已清空所有人脸数据');
}

// 识别人脸（比对特征）
export function recognizeFace(descriptor: Float32Array): string | null {
  if (faceDescriptors.length === 0) {
    console.warn('没有已存储的人脸数据');
    return null;
  }

  console.warn('开始人脸识别比对...');

  // 计算与已存人脸的欧氏距离（越小越相似）
  const distances = faceDescriptors.map(face => {
    const distance = faceapi.euclideanDistance(face.descriptor, descriptor);
    console.warn(`与${face.name}的距离: ${distance}`);
    return {
      name: face.name,
      distance: distance,
    };
  });

  // 按距离排序（从小到大）
  distances.sort((a, b) => a.distance - b.distance);

  // 获取最佳匹配
  const bestMatch = distances[0];
  console.warn('最佳匹配:', bestMatch);

  // 如果最佳匹配的距离小于阈值，则返回对应的名字
  const threshold = 0.5; // 调整阈值为0.50，在保证准确性的同时提高容错率
  console.warn(`距离阈值: ${threshold}, 最佳匹配距离: ${bestMatch.distance}`);

  if (bestMatch.distance <= threshold) {
    console.warn(`匹配成功: ${bestMatch.name}`);
    return bestMatch.name;
  } else {
    console.warn(
      `距离${bestMatch.distance}大于阈值${threshold}，判定为未知人脸`
    );
    return '未知';
  }
}

//数据持久化:
// 使用localStorage存储人脸数据
// 通过JSON序列化/反序列化处理Float32Array

// 模型加载:
// 加载了三个必要的模型用于完整的人脸识别流程
// 添加了canvas优化提示

// 人脸识别流程:
// 检测 → 关键点 → 特征提取 → 比对 → 结果

// 阈值选择:
// 欧氏距离阈值设为0.5，平衡了准确率和容错性

// 错误处理:
// 对关键操作进行了try-catch错误捕获
// 详细的日志记录便于调试
